﻿Imports DotNetNuke.Entities.Modules
Imports System.Linq
Imports DotNetNuke.Security.Permissions

Namespace DotNetNuke.Modules.Workflow

    Public Class WorkflowSettingsController

        Public Shared Sub CheckAndDisableModuleCachingIfWorkflowIsEnabled(ByVal moduleId As Integer, ByVal tabId As Integer, ByVal portalId As Integer)
            Dim objModules As New ModuleController
            Dim objWorkflow As New WorkflowStateController

            Dim workflowId As Integer = WorkflowSettingsController.GetWorkflow(moduleId, tabId, portalId).Value
            Dim workflowCount As Integer = objWorkflow.GetWorkflowStates(workflowId).Count

            If workflowCount > 1 Then
                'stupid dnn caching needs to be disabled
                Dim objModule As ModuleInfo = objModules.GetModule(moduleId, tabId, False)
                If objModule.CacheTime > 0 Then
                    objModule.CacheTime = -1
                    objModules.UpdateModule(objModule)
                End If
            End If
        End Sub

        Public Shared Function CanReview(ByVal iStateId As Integer, ByVal iWorkflowId As Integer, ByVal moduleInfo As ModuleInfo) As Boolean
            Dim result = WorkflowStatePermissionController.HasWorkflowStatePermission(WorkflowStatePermissionController.GetWorkflowStatePermissions(iStateId), "REVIEW")

            If Not result Then
                'we need to check if this is a draft, and if the user has edit rights... 
                Dim firstStateId = New WorkflowStateController().GetFirstWorkflowStateID(iWorkflowId)

                If iStateId = firstStateId Then
                    result = ModulePermissionController.CanEditModuleContent(moduleInfo)
                End If
            End If

            Return result
        End Function

        Public Shared Function CouldReview(ByVal iWorkflowId As Integer, ByVal moduleInfo As ModuleInfo) As Boolean
            Return WorkflowStatePermissionController.HasWorkflowStatePermission(WorkflowStatePermissionController.GetWorkflowStatePermissionsByWorkflowID(iWorkflowId), "REVIEW") OrElse ModulePermissionController.CanEditModuleContent(moduleInfo)
        End Function

        Public Shared Function CanManageWorkflow() As Boolean
            Dim objUser As Users.UserInfo = Users.UserController.GetCurrentUserInfo()
            If objUser.IsSuperUser OrElse objUser.IsInRole(GetPortalSettings().AdministratorRoleName) Then
                Return True
            End If
            Return False
        End Function


        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' GetMaximumVersionHistory retrieves the maximum number of versions to store for a module
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <param name="PortalID">The ID of the Portal</param>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Shared Function GetMaximumVersionHistory(ByVal PortalID As Integer) As Integer

            Dim intMaximumVersionHistory As Integer = -1

            ' get from portal settings
            intMaximumVersionHistory = Integer.Parse(Entities.Portals.PortalController.GetPortalSetting("MaximumVersionHistory", PortalID, "-1"))

            ' if undefined at portal level, set portal default
            If intMaximumVersionHistory = -1 Then
                intMaximumVersionHistory = 5 ' default
                Entities.Portals.PortalController.UpdatePortalSetting(PortalID, "MaximumVersionHistory", intMaximumVersionHistory)
            End If

            Return intMaximumVersionHistory

        End Function

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' UpdateWorkFlowID updates the currently active WorkflowID for the Portal
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <param name="PortalID">The ID of the Portal</param>
        ''' <param name="MaximumVersionHistory">The MaximumVersionHistory</param>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Shared Sub UpdateMaximumVersionHistory(ByVal PortalID As Integer, ByVal MaximumVersionHistory As Integer)

            ' data integrity check
            If MaximumVersionHistory < 0 Then
                MaximumVersionHistory = 5 ' default
            End If

            ' save portal setting
            Dim objPortalSettings As Portals.PortalSettings = Portals.PortalController.GetCurrentPortalSettings
            If PortalSecurity.IsInRole(objPortalSettings.AdministratorRoleName) Then
                Entities.Portals.PortalController.UpdatePortalSetting(PortalID, "MaximumVersionHistory", MaximumVersionHistory.ToString)
            End If

        End Sub

        Public Shared Function DisplayWorkflowDescription(ByVal WorkflowStateId As Integer) As String
            'If Not cboWorkflow.SelectedValue Is Nothing Then
            Dim objWorkflow As New WorkflowStateController
            Dim strDescription As String = ""
            Dim arrStates As ArrayList = objWorkflow.GetWorkflowStates(WorkflowStateId)
            If arrStates.Count > 0 Then
                For Each objState As WorkflowStateInfo In arrStates
                    strDescription = strDescription & " >> " & "<span class=""NormalBold"">" & objState.StateName & "</span>"
                Next
                strDescription = strDescription & "<br />" & CType(arrStates(0), WorkflowStateInfo).Description
            End If

            Return strDescription
            'End If
        End Function

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' GetWorkFlow retrieves the currently active Workflow for the Portal
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <param name="ModuleId">The ID of the Module</param>
        ''' <param name="PortalId">The ID of the Portal</param>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Shared Function GetWorkflow(ByVal ModuleId As Integer, ByVal TabId As Integer, ByVal PortalId As Integer) As KeyValuePair(Of String, Integer)
            Dim workFlowId As Integer = Null.NullInteger
            Dim workFlowType As String = Null.NullString

            ' get from module settings
            Dim moduleController As New Entities.Modules.ModuleController
            Dim settings As Hashtable = moduleController.GetModuleSettings(ModuleId)
            If Not settings("WorkflowID") Is Nothing Then
                workFlowId = Convert.ToInt32(settings("WorkflowID"))
                workFlowType = "Module"
            End If
            If workFlowId = Null.NullInteger Then
                ' if undefined at module level, get from tab settings
                settings = New TabController().GetTabSettings(TabId)
                If Not settings("WorkflowID") Is Nothing Then
                    workFlowId = Convert.ToInt32(settings("WorkflowID"))
                    workFlowType = "Page"
                End If
            End If

            If workFlowId = Null.NullInteger Then
                ' if undefined at tab level, get from portal settings
                workFlowId = Integer.Parse(Entities.Portals.PortalController.GetPortalSetting("WorkflowID", PortalId, "-1"))
                workFlowType = "Site"
            End If

            ' if undefined at portal level, set portal default
            If workFlowId = Null.NullInteger Then
                Dim objWorkflow As New WorkflowStateController
                Dim arrWorkflows As ArrayList = objWorkflow.GetWorkflows(PortalId)
                For Each objState As WorkflowStateInfo In arrWorkflows
                    ' use direct publish as default
                    If Null.IsNull(objState.PortalID) And objState.WorkflowName = "Direct Publish" Then
                        workFlowId = objState.WorkflowID
                        workFlowType = "Module"
                    End If
                Next
            End If

            Return New KeyValuePair(Of String, Integer)(workFlowType, workFlowId)
        End Function

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' UpdateWorkFlow updates the currently active Workflow
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <param name="WorkflowID">The ID of the Workflow</param>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Shared Sub UpdateWorkflow(ByVal ObjectID As Integer, ByVal WorkFlowType As String, ByVal WorkflowID As Integer, ByVal ReplaceExistingSettings As Boolean, ByVal FriendlyName As String)
            Dim tabController As New TabController
            Dim moduleController As New Entities.Modules.ModuleController

            Select Case WorkFlowType
                Case "Module"
                    moduleController.UpdateModuleSetting(ObjectID, "WorkflowID", WorkflowID.ToString)
                Case "Page"
                    tabController.UpdateTabSetting(ObjectID, "WorkflowID", WorkflowID.ToString)
                    If ReplaceExistingSettings Then
                        'Get All Modules on the current Tab
                        For Each kvp As KeyValuePair(Of Integer, Entities.Modules.ModuleInfo) In moduleController.GetTabModules(ObjectID)
                            ClearModuleSettings(FriendlyName, kvp.Value)
                        Next
                    End If
                Case "Site"
                    Entities.Portals.PortalController.UpdatePortalSetting(ObjectID, "WorkflowID", WorkflowID.ToString)
                    If ReplaceExistingSettings Then
                        'Get All Tabs aon the Site
                        For Each kvp As KeyValuePair(Of Integer, Entities.Tabs.TabInfo) In tabController.GetTabsByPortal(ObjectID)
                            tabController.DeleteTabSetting(kvp.Value.TabID, "WorkFlowID")
                        Next
                        'Get All Modules in the current Site
                        For Each objModule As Entities.Modules.ModuleInfo In moduleController.GetModules(ObjectID)
                            ClearModuleSettings(FriendlyName, objModule)
                        Next
                    End If
            End Select

        End Sub


        Private Shared Sub ClearModuleSettings(ByVal FriendlyName As String, ByVal objModule As Entities.Modules.ModuleInfo)
            Dim moduleController As New Entities.Modules.ModuleController
            If objModule.ModuleDefinition.FriendlyName = FriendlyName Then
                moduleController.DeleteModuleSetting(objModule.ModuleID, "WorkFlowID")
            End If
        End Sub

        Public Shared Function GetWorkflowModule(ByVal portalId As Integer) As ModuleInfo
            Dim moduleController As New ModuleController
            Return moduleController.GetModulesByDefinition(portalId, "Workflow").Cast(Of ModuleInfo)().FirstOrDefault(Function(m) Not m.IsDeleted AndAlso TabPermissionController.CanViewPage(New TabController().GetTab(m.TabID, m.PortalID, False)) AndAlso ModulePermissionController.CanViewModule(m))
        End Function

        Public Shared Function GetMyWorkURL(ByVal portalId As Integer, ByVal tabId As Integer, ByVal moduleId As Integer) As String
            Dim workflowModule As ModuleInfo = WorkflowSettingsController.GetWorkflowModule(portalId)

            'use should only see their work, for this module
            Dim MyWorkURL As String = NavigateURL(tabId, "MyWork", "mid=" & moduleId)

            If workflowModule IsNot Nothing AndAlso WorkflowSettingsController.CanManageWorkflow() Then
                'url is shared, and should show all pending work
                MyWorkURL = NavigateURL(workflowModule.TabID, "MyWork", "mid=" & workflowModule.ModuleID, "returnUrl=" & NavigateURL(tabId))
            End If

            Return MyWorkURL
        End Function
    End Class

End Namespace